home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ham Radio 2000 #2
/
Ham Radio 2000 - Volume 2.iso
/
HAMV2
/
TCP_IP
/
TNOS230S
/
REQSVR.C
< prev
next >
Wrap
C/C++ Source or Header
|
1997-08-18
|
18KB
|
678 lines
/* Those who hate GOTOs (like me) B E W A R E............
To save code space, extensive use of GOTOs was used to prevent
repetition of code. Could SURELY be cleaner, but it works!
KO4KS */
#include "global.h"
#include "ctype.h"
#include "commands.h"
#include "bm.h"
#ifdef MSDOS
#undef FA_DIREC
#define FA_DIREC 0x10
#else
#include "dirutil.h"
#endif
#include "ftpserv.h"
#if !defined(_lint)
static char rcsid[] OPTIONAL = "$Id: reqsvr.c,v 1.26 1997/08/19 01:19:22 root Exp root $";
#endif
extern int mailuser (FILE *data,const char *from,const char *to,const char *origto);
extern int groupcommand (char *action,char *group,char *user,int local, FILE **out, FILE *in);
extern char *Mbfwdinfo;
extern char shortversion[], SysMessage[];
extern char *Callserver;
extern short SecureTelnet;
#ifdef RMAIL
static void rmailit (FILE *fp,char *from, char *to, char *subject,long startat);
#endif
#if defined(REQSVR) || defined(RMAIL) || defined(MAILFILTER)
static int handleError (FILE *fp,char *from, char *str);
#endif
#if defined(REQSVR) || defined(RMAIL) || defined(DELEGATE) || defined(MAILFILTER)
static void getfield (char *into, char *from, int fieldtype);
#endif
static void rdaemon_str (char *str,const char *replyto, const char *from, const char *to, const char *msg, const char msgtype, int mode);
char *reqsvr_filter_subject = NULLCHAR;
int reqsvr_bypass_permissions = 0;
static char DAEMONSTR[] = "%sREQSVR@%s (Mail Delivery Subsystem)\n";
static void
rdaemon_str(str, replyto, from, to, msg, msgtype, mode)
char *str;
const char *replyto;
const char *from, *to;
const char *msg, msgtype;
int mode;
{
FILE *fp;
fp = tmpfile();
if (fp) {
fputs (str, fp);
rewind (fp);
(void) rdaemon (fp, replyto, from, to, msg, msgtype, mode);
(void) fclose (fp);
}
}
int
rdaemon(data, replyto, from, to, msg, msgtype, mode)
FILE *data; /* pointer to rewound data file */
const char *replyto;
const char *from, *to;
const char *msg, msgtype;
int mode;
{
time_t t;
FILE *tfile;
char buf[LINELEN], *newaddr, *orgto;
long mid;
if((tfile = tmpfile()) == NULLFILE)
return -1;
/* if (to == NULLCHAR)
mode = 1; */
to = strdup ((to == NULLCHAR) ? "sysop" : to);
orgto = strdup (to);
if((newaddr = rewrite_address(to, 0)) != NULLCHAR) {
free (to);
to = newaddr;
}
(void) time(&t);
fprintf(tfile,Hdrs[RECEIVED]);
fprintf(tfile,"from %s ",Hostname);
mid = get_msgid(0);
#ifdef MBFWD
fprintf(tfile,"by %s (%s) with SMTP\n\tid AA%ld ; %s",
Hostname, (Mbfwdinfo != NULLCHAR) ? Mbfwdinfo : shortversion, \
mid, ptime(&t));
#else
fprintf(tfile,"by %s (%s) with SMTP\n\tid AA%ld ; %s",
Hostname, shortversion, mid, ptime(&t));
#endif
fprintf(tfile,"%s%c\n",Hdrs[BBSTYPE], msgtype);
fprintf(tfile,"%s%s",Hdrs[DATE],ptime(&t));
mid = get_msgid(1);
fprintf(tfile,"%s<%ld@%s>\n",Hdrs[MSGID],mid,Hostname);
if (from == NULLCHAR)
fprintf(tfile,DAEMONSTR,Hdrs[FROM],Hostname);
else
fprintf(tfile,"%s%s\n",Hdrs[FROM],from);
fprintf(tfile,"%s%s\n",Hdrs[TO], strlwr(orgto));
if (replyto != NULLCHAR)
fprintf(tfile, "%s%s\n", Hdrs[REPLYTO], replyto);
fprintf(tfile,"%s%s\n\n",Hdrs[SUBJECT], msg);
kwait (NULL);
if (data != NULLFILE) {
if (mode)
fprintf(tfile," ===== Message %sfollows ====\n", (msg == SysMessage) ? "" : "header ");
while(fgets(buf,sizeof(buf),data) != NULLCHAR) {
if(mode && buf[0] == '\n')
break;
kwait (NULL);
fputs(buf,tfile);
}
/* if (mode && (msg != SysMessage))
fprintf(tfile," ===== Message Stored ====\n"); */
} else
fputc ('\n', tfile);
rewind(tfile);
sprintf (buf, "REQSVR@%s", Hostname);
(void) mailuser(tfile, (from) ? from : buf, to, orgto);
free (to);
free (orgto);
(void) fclose(tfile);
kwait (NULL);
return 0;
}
int
dosendmail (argc,argv,p)
int argc;
char *argv[];
void *p OPTIONAL;
{
FILE *fp;
char *from, *to, *data, *subj;
char buf[LINELEN];
to = argv[1];
if (argc > 4) {
from = argv[2];
subj = argv[3];
data = argv[4];
} else {
sprintf (buf, "sysop@%s", Hostname);
from = buf;
subj = argv[2];
data = argv[3];
}
if (*data == '<') {
/* filename given */
if ((fp = fopen (&data[1], "r")) == NULL) {
tprintf ("SendMail: Error opening file '%s'!", &data[1]);
return 0;
}
(void) rdaemon (fp, NULLCHAR, from, to, subj, 'P', 0);
(void) fclose (fp);
} else /* string data given */
rdaemon_str (data, NULLCHAR, from, to, subj, 'P', 0);
smtptick (NULL); /* wake SMTP to send that mail */
return 0;
}
#if defined(REQSVR) || defined(RMAIL) || defined(DELEGATE) || defined(MAILFILTER) || defined(WPAGES) || defined(TUTOR)
static void
getfield (into, from, fieldtype)
char *into, *from;
int fieldtype;
{
char *cp, *temp;
cp = &from[strlen(Hdrs[fieldtype])];
if (*cp == '"') {
cp++;
if ((temp = strchr (cp, '"')) != NULLCHAR)
cp = temp+1;
}
if ((temp = strchr (cp, '<')) != NULLCHAR) {
cp = temp+1;
if ((temp = strchr (cp, '>')) != NULLCHAR)
*temp = 0;
}
if ((temp = strpbrk (cp, " \t")) != NULLCHAR)
*temp = 0;
strcpy (into, cp);
}
void
parseheader (fp, from, subject, to, bid, buf, startat)
FILE *fp;
char *from, *subject, *to, *bid, *buf;
long *startat;
{
char *cp, *temp;
int fieldtype;
rewind (fp);
subject[0] = from[0] = 0;
while(fgets(buf,128,fp) != NULLCHAR) {
if(buf[0] == '\n')
break;
rip (buf);
fieldtype = htype(buf);
if (fieldtype == FROM) {
trimright (buf);
getfield (from, buf, fieldtype);
}
if (fieldtype == SUBJECT) {
trimright (buf);
cp = &buf[strlen(Hdrs[SUBJECT])];
cp = skipwhite(cp);
if (*cp == '"') {
cp++;
if ((temp = strchr (cp, '"')) != NULLCHAR)
*temp = 0;
}
strcpy (subject, cp);
}
if ((to != NULLCHAR) && (fieldtype == TO)) {
trimright (buf);
getfield (to, buf, fieldtype);
}
if ((bid != NULLCHAR) && (fieldtype == MSGID)) {
trimright (buf);
getfield (bid, buf, fieldtype);
}
}
*startat = ftell (fp);
if (fgets(buf,128,fp) != NULLCHAR) {
if(!strnicmp (buf, "R:", 2)) {
while(fgets(buf,128,fp) != NULLCHAR) {
if(buf[0] == '\n')
break;
}
*startat = ftell (fp);
}
}
kwait (NULL);
}
#endif
#if defined(REQSVR) || defined(RMAIL) || defined(MAILFILTER)
static int
handleError (fp, from, str)
FILE *fp;
char *from, *str;
{
rewind (fp);
(void) rdaemon (fp, NULLCHAR, NULLCHAR, from, str, 'P', 1);
rewind (fp);
(void) rdaemon (fp, NULLCHAR, NULLCHAR, NULLCHAR, str, 'P', 1);
return 0; /* pass the message back */
}
#endif
#ifdef RMAIL
static char rmailerror[] = "Rmail Error";
static void
rmailit (fp, from, to, subject, startat)
FILE *fp;
char *from, *to, *subject;
long startat;
{
char *thisto;
while (to && *to) {
thisto = to;
to = strchr (to, ',');
if (to) {
*to++ = 0;
to = skipwhite (to);
}
if (!strnicmp (thisto, "rmail@", 6))
continue;
kwait (NULL);
fseek (fp, startat, SEEK_SET);
(void) rdaemon (fp, NULLCHAR, from, thisto, subject, 'P', 0);
}
}
int
rmail (fp, from)
FILE *fp;
const char *from OPTIONAL;
{
char buf[512], subject[256], realfrom[128], *to = NULLCHAR;
long startat;
parseheader (fp, realfrom, subject, NULLCHAR, NULLCHAR, buf, &startat);
if (realfrom[0] && subject[0]) {
fseek (fp, startat, 0);
while(fgets(buf,512,fp) != NULLCHAR) {
if(buf[0] == '\n')
break;
if (htype(buf) == TO) {
if (to != NULLCHAR) { /* more than 1 To: - ERROR */
free (to);
to = NULLCHAR;
break;
} else {
rip(buf);
to = strdup (&buf[4]);
}
}
}
if (to != NULLCHAR) {
rmailit (fp, realfrom, to, subject, startat);
free (to);
return 1;
}
}
return (handleError (fp, realfrom, rmailerror));
}
#endif
#if defined(REQSVR) || defined(MAILFILTER)
int
reqsvr (fp, from)
FILE *fp;
const char *from OPTIONAL;
{
char buf[128], smallbuf[2];
char name[128], path[128], realfrom[128];
char subject[LINELEN], *file, cmd, *cp = path, action = 'I', *ptr, *ptr2;
char *ptr3, *cp1, *cp2;
int anony = 1, mode = RETR_CMD, found = 0 /*, first = 0*/ ;
FILE *out, *out2;
long prev, msgdata, privs;
unsigned attr = 0;
int overrideperm = 0;
#ifdef SAMCALLB
int err;
#endif
#if defined(SAMCALLB) || defined(CALLCLI)
struct mbx *mb;
#endif
parseheader (fp, realfrom, subject, NULLCHAR, NULLCHAR, buf, &prev);
if (reqsvr_filter_subject) {
strcpy (subject, reqsvr_filter_subject);
reqsvr_filter_subject = NULLCHAR;
}
if (reqsvr_bypass_permissions) {
overrideperm = 1;
reqsvr_bypass_permissions = 0;
}
sprintf(buf,"%s/reqsvr.log", LOGdir);
if((out = fopen(buf,APPEND_TEXT)) != NULLFILE) {
time_t t;
(void) time(&t);
fprintf (out, "Received from %s (%s) on %s", realfrom, subject, ptime(&t));
(void) fclose (out);
}
if (!*subject)
return 0; /* we are konfuzd! No subject!?!? */
kwait (NULL);
#if 0
/*
** This code to detect R: headers is a problem.
** parseheader() already seeks past R: Headers
** so the first line seen here is a blank line.
** This causes any non blank lines to be skipped
** until another blank line is encountered.
** (sometimes the entire message !) -- N0EIR
*/
do {
if (fgets(buf,128,fp) == NULLCHAR)
break;
if (!first && *buf == '\n')
strcpy (buf, "R:");
if (!strnicmp (buf, "R:", 2))
found = 1;
first = 1;
} while (*buf != '\n');
if (!found)
fseek (fp, prev, SEEK_SET);
#endif
/* else
fgets(buf,128,fp); */ /* strip off blank line */
/* now the fix for FBB/PRMBS/TNOS adding RFC 822-type lines to messages */
prev = ftell (fp);
if (fgets (buf, 128, fp) != NULLCHAR) {
if (strnicmp (buf, "From:", 5) && strnicmp (buf, "Date:", 5) && strnicmp (buf, "Message-Id:", 11))
fseek (fp, prev, SEEK_SET);
else do {
if (fgets (buf, 128,fp) == NULLCHAR)
break;
} while (*buf != '\n');
}
msgdata = ftell (fp);
strncpy (name, realfrom, 40);
file = strchr (name, '@');
if (file)
*file = 0;
cmd = (char) tolower (*subject);
/* get senders permissions and default path */
privs = userlogin (name, NULLCHAR, &cp, 128, &anony);
file = skipnonwhite (&subject[1]);
file = skipwhite (file);
cp1 = strdup(cp);
if ((cp2 = strchr(cp1, ';')) != NULLCHAR)
*cp2 = '\0';
file = pathname (cp1, file);
free (cp1);
#ifdef DOS_GETFILEATTR
(void) _dos_getfileattr (file, &attr);
#endif
if (!strnicmp (subject, "infor", 5))
cmd = 'f'; /* inform */
if (!strnicmp (subject, "uni", 3))
cmd = 'n'; /* uninform */
if (!strnicmp (subject, "uns", 3))
cmd = 'c'; /* unsubscribe */
switch (cmd) {
case 'i': /* info */
case 'h': /* help */
free (file);
file = pathname (Helpdir, "reqsvr.hlp");
if ((out = fopen (file, READ_TEXT)) != NULLFILE)
goto okay;
sprintf (buf, "Not Found %s", subject);
goto error;
case 'g': /* group commands */
ptr = skipnonwhite (&subject[1]);
ptr = skipwhite (ptr);
cmd = (char) tolower (*ptr);
if (cmd != 's' && cmd != 'u' && cmd != 'l')
if (privs == -1 || !(privs & SYSOP_CMD))
goto denied;
ptr2 = skipnonwhite (ptr);
action = *ptr2;
*ptr2++ = 0;
ptr2 = skipwhite (ptr2);
ptr3 = strdup (ptr2);
ptr3 = strcat (ptr3, ".hlp");
switch (cmd) {
case 's':
case 'u':
case 'a':
case 'd':
case 'i':
case 'l': out = NULLFILE;
found = groupcommand (ptr, (action) ? ptr2 : NULLCHAR, realfrom, 0, &out, fp);
*(--ptr2) = action;
if (found) {
if (cmd == 's') {
file = pathname (Helpdir, ptr3);
if ((out = fopen (file, READ_TEXT)) != NULLFILE)
goto okay;
}
if (cmd == 'l')
goto done;
else
goto okay;
} else
goto denied;
default: *(--ptr2) = action;
goto confuzed;
}
case 'q': /* return callbook server data */
#if defined(SAMCALLB) || defined(CALLCLI)
ptr = skipnonwhite (&subject[1]);
ptr = skipwhite (ptr);
if((out = tmpfile()) != NULLFILE){
#ifdef SAMCALLB
if ((err = cb_lookup (0, ptr, out)) != 0) {
if (err == 1) {
#endif
if (Callserver && *Callserver) {
char *newargv[3], bufport[8], cmdbuf[4];
mb = (struct mbx *)callocw(1,sizeof(struct mbx));
mb->quickfile = out;
strcpy (cmdbuf, "C");
newargv[0] = cmdbuf;
newargv[1] = Callserver;
sprintf(bufport,"%d",IPPORT_CALLDB);
newargv[2] = bufport;
mb->startmsg = mallocw(80); /* is freed each time by gw_connect() */
sprintf(mb->startmsg,"%s\n", ptr);
SecureTelnet = 0;
strcpy (mb->name, "reqsvr");
mb->stype = '+';
(void) dombtelnet(3,newargv,mb);
free (mb);
} else
goto confuzed;
#ifdef SAMCALLB
} else
fprintf (out, "Amateur callsign '%s' not found or invalid\n", ptr);
}
#endif
goto okay;
}
#endif
goto ioerror;
case 'v': /* return version info */
if((out = tmpfile()) != NULLFILE){
fprintf (out, "Currently running %s at %s\n", Version, Hostname);
goto okay;
}
goto ioerror;
case 'u': /* upload a file */
mode = STOR_CMD; /*lint !e616 */
case 's': /* subscribe to a file */
case 'c': /* unsubscribe to a file */
case 'f': /* inform of changes to a file */
case 'n': /* uninform of changes to a file */
case 'w': /* send a directory */
case 'd': /* download a file */
if ((!overrideperm && privs == -1) || !permcheck(path, privs, mode, file)) {
denied: sprintf (buf, "Denied %s", subject);
goto error;
}
switch (cmd) {
case 'c': /* unsubscribe */
case 'n': /* uninform */
case 's': /* subscribe */
case 'f': /* inform */
if (cmd == 'c' || cmd == 's') /* subscribe functions */
action = 'S';
if(attr & FA_DIREC) { /* whole dir */
smallbuf[0] = '/';
smallbuf[1] = 0;
cp = smallbuf;
} else {
cp = strrchr (file, '/');
if (cp)
*cp++ = 0;
}
sprintf(buf,"%s/reqsvr.dat",file);
if (cmd == 's' || cmd == 'f') { /* adding functions */
if((out = fopen(buf,APPEND_TEXT)) != NULLFILE) {
fprintf (out, "%s %s %c\n", cp, realfrom, action);
goto complete;
}
goto ioerror;
} else { /* removing functions */
if((out = fopen(buf,UPDATE_TEXT)) != NULLFILE) {
while(fgets(buf,128,out) != NULLCHAR) {
char *tmp1;
kwait (NULL);
rip (buf);
if (cp && !strnicmp (buf, cp, strlen (cp))) {
tmp1 = strchr (buf, ' ');
if (tmp1)
if (!strnicmp (++tmp1, realfrom, strlen (realfrom)))
if (buf[strlen(buf) - 1] == action) {
fseek (out, (long) (ftell (out) - 3), SEEK_SET);
fputc ('N', out);
break;
}
}
}
}
goto complete;
}
case 'w': /* what (dir) */
if((out = dir(file, 1)) == NULLFILE)
goto ioerror;
goto okay;
case 'u': /* upload */
if ((out = fopen (file, WRITE_TEXT)) == NULLFILE) {
ioerror: sprintf (buf, "IO Error %s", subject);
goto error;
}
while(fgets(buf,128,fp) != NULLCHAR) {
kwait (NULL);
fputs(buf,out);
}
(void) fclose (out);
cp = strrchr (file, '/');
if (cp)
*cp++ = 0;
sprintf(buf,"%s/reqsvr.dat",file);
if((out = fopen(buf,READ_TEXT)) != NULLFILE) {
if((out2 = tmpfile()) != NULLFILE)
fprintf (out2, "File changed by %s\n", realfrom);
while(fgets(name,128,out) != NULLCHAR) {
kwait (NULL);
if (!cp)
goto confuzed;
if (*name == '/' || !strnicmp (name, cp, strlen (cp))) {
ptr = strrchr (name, ' ');
if (!ptr)
goto confuzed;
*ptr = 0;
action = ptr[1];
ptr = strchr (name, ' ');
if (!ptr)
goto confuzed;
ptr++;
switch (action) {
case 'S':
sprintf (buf, "Subscribe %s/%s", file, cp);
fseek (fp, msgdata, SEEK_SET);
(void) rdaemon (fp, NULLCHAR, NULLCHAR, ptr, buf, 'P', 0);
break;
case 'I':
sprintf (buf, "Inform %s/%s", file, cp);
if (out2 != NULLFILE)
rewind (out2);
(void) rdaemon (out2, NULLCHAR, NULLCHAR, ptr, buf, 'P', 0);
break;
default:
break;
}
}
}
if (out2 != NULLFILE)
(void) fclose (out2);
}
complete: if (out != NULLFILE) {
(void) fclose (out);
out = NULLFILE;
}
if (!strnicmp (subject, "uploadblind", 11) || !strnicmp (subject, "ub", 2))
goto done;
goto okay;
case 'd': /* download */
if ((out = fopen (file, READ_TEXT)) == NULLFILE)
goto ioerror;
okay: sprintf (buf, "Accepted %s", subject);
if (out != NULLFILE)
rewind (out);
(void) rdaemon (out, NULLCHAR, NULLCHAR, realfrom, buf, 'P', 0);
if (out != NULLFILE)
(void) fclose (out);
break;
default:
break;
}
break;
confuzed:
default: sprintf (buf, "Unknown %s", subject); /*lint !e616 */
goto error;
}
done: free (file);
return 1; /* we handled it, here! */
error: free (file);
return (handleError (fp, realfrom, buf));
}
#endif